#include <iostream>
#include <string>
#include <vector>
#include <unistd.h>
#include <pthread.h>
#include <cstdio>
#include <cstring>
#include <sched.h>



int *p = nullptr;

void *threadrun(void *args)
{
    int a = 123;

    p = &a;

    while(true) {sleep(1);}
}

int main()
{
    pthread_t tid;
    pthread_create(&tid, nullptr, threadrun, nullptr);

    while(true)
    {
        std::cout << "*p : " << *p << std::endl;
        sleep(1);
    }

    pthread_join(tid, nullptr);
    return 0;
}





// 进程间的通讯能不能实现？？？ 当然可以 在某个线程 创建一个 管道 不就行了
// 进程间通信？？？ 退出码？
// 子进程执行的函数
#include <sys/types.h>
#include<sys/wait.h>
const int SIZE = 1024 * 1024; //for test debug
static int func(void *arg)
{
    int cnt = 5;
    while (cnt--)
    {
        printf("Child process: PID = %d\n", getpid());
        sleep(1);
    }
    return 0;
}

int main()
{
    char *stack = (char*)malloc(SIZE);
    if(stack == nullptr)
    {
        perror("malloc");
        exit(EXIT_FAILURE);
    }

    pid_t pid = clone(func, stack + SIZE, CLONE_VM | SIGCHLD, nullptr);
    if(pid ==-1)
    {

        free(stack);
        exit(EXIT_FAILURE);
    }

    printf("Parent process: PID = %d, Child PID = %d\n", getpid(), pid);

    //flags = SIGCHLD：子进程退出时向父进程发送 SIGCHLD 信号（类似 fork() 的行为）。
    //未设置 CLONE_VM、CLONE_FS 等共享标志，因此子进程是独立的。
    // 所以这里用waitpid 等待子进程 是完全可以的；
    
    while(waitpid(pid,nullptr, 0) == -1)
    {
        perror("waitpid");
        free(stack);
        exit(EXIT_FAILURE);
    }
    free(stack);

    return 0;
}


// //创建多线程

// void* routine(void* args)
// {
//     std::string name = static_cast<const char*> (args);

//     int cnt = 3;
//     while(cnt--)
//     {
//         std::cout << "线程名字 name: " << name << std::endl;
//         sleep(1);
//     }

//     return nullptr;
// }

// int main()
// {
//     //char id[64];
//     std::vector<pthread_t> t;
//     for(int i = 1; i <= 10; i++)
//     {
//         pthread_t tid;

//         char* id = new char(64);
//         snprintf(id, 64, "pthread-%d", i);
//         pthread_create(&tid, nullptr, routine, (void*)id);
//         t.push_back(tid);
//     }

//     for(int i = 1; i <= 10; i++)
//     {
//         int n = pthread_join(t[i], nullptr);
//         if(n == 0)
//         {
//             std::cout << "等待线程成功 tid: " << t[i] << std::endl;
//         }
//     }

//     return 0;
// }



// //1 main线程结束，代表主线程结束， 一般也进程就结束了
// //2  新线程对应的入口函数，运行结束，代表当前线程运行结束
// //3  给线程传递的 参数和返回值，可以是任意类型包括对象；自定义类型

// struct task
// {
//     public:
//     task(int a, int b)
//     :_a(a),
//     _b(b)
//     {}
//     int Execute()
//     {
//         return _a + _b;
//     }

//     ~task()
//     {}
//     private:
//     int _a;
//     int _b;
// };

// struct Result
// {
//     public:
//     Result(int result):_result(result)
//     {}

//     int GetResult() { return _result; }

//     ~Result()
//     {}
//     private:
//     int _result;
// };

// // 线程终止的问题
// // 1. 线程的入口函数，进行return就是线程终止
// // 注意: 线程不能用exit()终止，因为exit是终止进程的！！！！！
// // 2. pthread_exit();
// // 3. 线程如果被取消，退出结果是-1【PTHREAD_CANCELED】
// // void* p : 开辟空间的
// void* routine(void* argc)
// {
//     //pthread_detach(pthread_self());
//     //std::cout << "新线程被分离" << std::endl;
//     int cnt = 5;
//     while(cnt--)
//     {
//         std::cout << "new线程的名字:" << std::endl;
//         sleep(1);
//     }
//     //sleep(3);
//     task *t = static_cast<task*>(argc);
//     //sleep(100);
//     Result *res = new Result(t->Execute());
//     //sleep(1);
//     std::cout << res->GetResult() << std::endl;
//     return (void**)res;
//     // exit(13);
//     //pthread_exit(res);
//     // std::cout << "haha, 新线程不应该看到这里" << std::endl;
//     //return nullptr;
    
// }

// // 如果主线程不想再关心新线程，而是当新线程结束的时候，让他自己释放？？
// // 设置新线程为分离状态
// // 技术层面:  线程默认是需要被等待的，joinable。如果不想让主线程等待新线程
// // 想让新线程结束之后，自己退出，设置为分离状态(!joinable or detach)  // TODO
// // 理解层面：线程分离，主分离新，新把自己分离。
// // 分离的线程，依旧在进程的地址空间中，进程的所有资源，被分离的线程，依旧可以访问，可以操作。
// // 主不等待新线程。
// // 分离操作
// // 如果线程被设置为分离状态，不需要进行join，join会失败！！

// int main()
// {
//     pthread_t tid;
//      task* t = new task(1, 2);
//     pthread_create(&tid, nullptr, routine, (void*)t);


//     Result* ret = nullptr;
//     sleep(1);
//     pthread_cancel(tid);
//     std::cout << "取消线程tid: " << tid << std::endl;
//     int n = pthread_join(tid, (void**)&ret);
//     //int n = pthread_join(tid, (void**)&ret);

//     //int n = pthread_join(tid, nullptr);
//     if(n != 0)
//     {
//         std::cout << "pthread_join error :" << strerror(n) << std::endl;
//     }
//     else
//     {
//         std::cout << "success pthread_join" << std::endl;
//     }
//     //int m = ret->GetResult();
//     std::cout << "新线程结束, 运行结果: " << (long long int)ret << std::endl;


//     return 0;
// }


// int main()
// {
//     pthread_t tid;
//    // task* t = new task(1, 2);
//     //pthread_create(&tid, nullptr, routine, (void*)t);
    
//     pthread_create(&tid, nullptr, routine, (void*)"thread-1");
    
//     // int cnt = 5;
//     // while(cnt--)
//     // {
//     //     std::cout << "main线程的名字: " << std::endl;
//     //     sleep(1);
//     //     pthread_cancel(tid);
//     // }

//     // void* res;
//     // int n = pthread_join(tid, &res);
//     // if(n != 0)
//     // {
//     //     std::cout << "pthread_join error :" << strerror(n) << std::endl;
//     // }
//     // else
//     // {
//     //     std::cout << "success pthread_join" << std::endl;
//     // }


//     sleep(3);
//     pthread_cancel(tid);
//     std::cout << "新线程被取消" << std::endl;

//     // void *ret = nullptr;
//     // // 默认线程无异常
//     // pthread_join(tid, &ret); // pthread_join: 拿到的返回值，就是线程退出设定的返回值
//     // std::cout << "新线程结束, 运行结果: " << (long long)ret << std::endl;

//     Result* ret = nullptr;
//     int n = pthread_join(tid, (void**)&ret);
//     if(n != 0)
//     {
//         std::cout << "pthread_join error :" << strerror(n) << std::endl;
//     }
//     else
//     {
//         std::cout << "success pthread_join" << std::endl;
//     }
//     int m = ret->GetResult();
//     std::cout << "新线程结束, 运行结果: " << m << std::endl;


//     return 0;
// }